/*
 * @@name:    taskloop_dep.2
 * @@type:    C
 * @@operation:    compile
 * @@expect:    success
 * @@version:    omp_6.0
 */
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

void process_work_b(int n, float** B) {
// Dependences for taskloop iterations in multi-dimensional loop nest

// TL4 taskloop + collapse
#pragma omp taskloop collapse(2) nogroup
   for (int i = 1; i < n; i++) {
      for (int j = 1; j < n; j++) {
#pragma omp task_iteration depend(inout : B[i][j]) \
    depend(in : B[i - 1][j], B[i][j - 1])
         B[i][j] += B[i][j] * B[i - 1][j] * B[i][j - 1];
      }
   }

// T5 other task
#pragma omp task depend(in : B[n - 1][n - 1])
   printf("B[n-1][n-1] = %f\n", B[n - 1][n - 1]);
}

int main() {
   int n = 10;

   // Allocate memory for pointer array
   float** B = (float**)malloc(n * sizeof(float*));
   for (int i = 0; i < n; i++) {
      B[i] = (float*)malloc(n * sizeof(float));
   }

   // Initialize array
   for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
         B[i][j] = (float)(i + j);  // Example initialization
      }
   }

// Execute parallel work
#pragma omp parallel
#pragma omp single
   process_work_b(n, B);

// Wait for all tasks to complete
#pragma omp taskwait

   printf("B[0][0] = %f\n", B[0][0]);

   // Free memory
   for (int i = 0; i < n; i++) {
      free(B[i]);
   }
   free(B);
   getchar();
   return 0;
}